﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Speech.Recognition;

namespace CodeTalk.CTSpeechCommands
{
    class InsertHidden : SpeechCommand
    {
        private string[] variables = null;

        private static void AddToChoices(CodeSymbol cs, Choices symbolChoices, List<string> spokenVariables)
        {
            if (cs.Category == SymbolCategory.Hidden)
            {
                symbolChoices.Add(new SemanticResultValue("hidden " + cs.SpokenForm, cs.WrittenForm));
                spokenVariables.Add(cs.SpokenForm);
            }
        }

        internal override GrammarBuilder GrammarBld(Context context, Context[] libraries)
        {
            if (context == null)
            {
                variables = new string[] { };
                return null;
            }
            List<string> spokenVariables = new List<string>();

            Choices symbolChoices = new Choices();
            foreach (var s in context.Symbols)
                AddToChoices(s, symbolChoices, spokenVariables);

            foreach (var lib in libraries)
            {
                foreach (var s in lib.Symbols)
                    AddToChoices(s, symbolChoices, spokenVariables);
            }
            variables = spokenVariables.ToArray();
            if (spokenVariables.Count != 0)
            {
                GrammarBuilder gb = new GrammarBuilder();
                gb.Append(new SemanticResultKey("WrittenForm", symbolChoices));
                return gb;
            }
            else
                return null;
        }

        public override string Name
        {
            get { return "Insert hidden"; }
        }

        public override string Description
        {
            get { return "Inserts a variable of category Hidden. "; }
        }

        public override string GetAlternativesFeedback(string recognizedText, SemanticValue semValue)
        {
            return (string)semValue["WrittenForm"].Value;
        }

        internal override bool CanSpokenFormMatch(string spokenForm)
        {
            return variables.Contains<string>(spokenForm);
        }

        internal override object Execute(SpeechMode callingMode, string recognizedText, SemanticValue semValue)
        {
            string textToType = (string)semValue["WrittenForm"].Value;
            callingMode.CurrentOutputHandler.SendKeys(textToType);
            callingMode.CurrentGuiHandler.SetPrimaryFeedback(textToType);
            return "^z";
        }
    }
}
